#include "bib_Abrir_Configuracion.h"

static int obtenerConfiguracion(char *cadena, CONFIG_EST *config);	/*Coloca cadena en el miembro correcto de la variable global (lo convierte si es valor numerico)*/
static int ValidaPuerto(int);	/*Valida que el puerto se encuentre en un rango correcto*/

extern char nivelLog;
extern struct EST_DISCO disco;
extern char modoInicio;

int abrirConfiguracion(CONFIG_EST *config){

	char cadenaLeida[TAM_MAX];
	FILE *archivo;
	
	nivelLog = DEBUG;
	
	if (!(archivo = fopen(ARCHIVO_CONFIGURACION, "r"))){
		imprimirLog(ERROR, "No se pudo abrir el archivo de configuracion", ARCHIVO_CONFIGURACION);
		return FIN_ERROR;
	}
	imprimirLog(DEBUG, "Archivo de configuracion abierto", "");
	
	while (fgets(cadenaLeida, TAM_MAX, archivo))
		if (obtenerConfiguracion(cadenaLeida, config) == FIN_ERROR)
			return FIN_ERROR;
	
	if (fclose(archivo)){
		imprimirLog(WARNING, "No se pudo cerrar el descriptor del archivo de configuracion", "");
		return FIN_WARNING;
	}
	else{
		imprimirLog(DEBUG, "Archivo de configuracion cerrado", "");
		return FIN_OK;
	}
}
/*=====================================================================================*/
static int ValidaPuerto(int puerto){

	if (puerto < 0){
		imprimirLogNumerico(ERROR, "Numero de puerto Invalido:", puerto);
		return FIN_ERROR;
	}

	if (puerto < 1024){
		imprimirLog(WARNING, "El numero de puerto debe ser mayor a 1024", "");
		return FIN_WARNING;
	}
	
	return FIN_OK;
}
/*=====================================================================================*/
static int obtenerConfiguracion(char * cadena, CONFIG_EST *config){

	char *ptr, *pszValor;
	char tokens[3 + 1] = "=\n\r";
	ptr = strtok(cadena, tokens);
	pszValor = strtok(NULL, tokens);
	
	if (!strcmp("NivelLog", ptr)){  /*Debe ser 3 o mas para que muestre todos los tipos de log */
		nivelLog = atoi(pszValor);		
		imprimirLog(INFO, "Nivel del Log:", pszValor);
	}

	else if (!strcmp("ModoInicio", ptr)){  /*Debe ser 3 o mas para que muestre todos los tipos de log */
		if (!strcmp(pszValor, "Connect"))
			modoInicio = CONNECT;
		else if (!strcmp(pszValor, "Listen"))
			modoInicio = LISTEN;
		else{
			imprimirLog(ERROR, "Modo de Inicio incorrecto. Valores Correctos: Connect o Listen", "");
			return FIN_ERROR;
		}
		imprimirLog(INFO, "Modo de Inicio:", pszValor);
	}

	else if (!strcmp("IP", ptr)){
		strcpy(config->ip, pszValor);
		if (modoInicio == CONNECT)
			imprimirLog(INFO, "IP PRAID:", pszValor);
	}
			
	else if (!strcmp("Puerto", ptr)){
		config->puerto = atoi(pszValor);
		if (ValidaPuerto(config->puerto) == FIN_ERROR)
			return FIN_ERROR;
		if (modoInicio == CONNECT)
			imprimirLog(INFO, "Puerto PRAID:", pszValor);
		else
			imprimirLog(INFO, "Mi puerto:", pszValor);
	}
	
	else if (!strcmp("IdDisco", ptr)){
		config->idDisco = atoi(pszValor);
		imprimirLog(INFO, "ID Disco:", pszValor);
	}

	else if (!strcmp("ArchivoPersistencia", ptr)){
		sprintf(config->archivoPersistencia, "./%s", pszValor);
		imprimirLog(INFO, "Archivo de persistencia:", pszValor);
	}

	else if (!strcmp("Cilindros", ptr)){
		disco.chs.cilindro = atol(pszValor);
		imprimirLog(INFO, "Cant. cilindros:", pszValor);
	}

	else if (!strcmp("Cabezales", ptr)){
		disco.chs.cabezal = atol(pszValor);
		imprimirLog(INFO, "Cant. cabezales:", pszValor);
	}

	else if (!strcmp("Sectores", ptr)){
		disco.chs.sector = atol(pszValor);
		imprimirLog(INFO, "Cant. sectores:", pszValor);
	}

	else if (!strcmp("TiempoLectura", ptr)){
		disco.tiempoLectura = atol(pszValor);
		imprimirLog(INFO, "Tiempo de lectura:", pszValor);
	}

	else if (!strcmp("TiempoEscritura", ptr)){
		disco.tiempoEscritura = atol(pszValor);
		imprimirLog(INFO, "Tiempo de escritura:", pszValor);
	}

	else if (!strcmp("RPM", ptr)){
		disco.tiempoEntreSectores = 60000 / (atol(pszValor) * disco.chs.sector);
		imprimirLogNumerico(INFO, "Tiempo entre sectores:", disco.tiempoEntreSectores);
	}

	else if (!strcmp("TiempoEntrePistas", ptr)){
		disco.tiempoEntrePistas = atol(pszValor);
		imprimirLog(INFO, "Tiempo entre pistas:", pszValor);
	}

	else if (!strcmp("AlgoritmoPlanificacion", ptr)){  /*Debe ser 3 o mas para que muestre todos los tipos de log */
		if (!strcmp(pszValor, "SSTF"))
			disco.planificador = SSTF;
		else if (!strcmp(pszValor, "CLOOK"))
			disco.planificador = CLOOK;
		else{
			imprimirLog(ERROR, "Algoritmo de planificacion no admitido. Valores Correctos: SSTF o CLOOK", "");
			return FIN_ERROR;
		}
		imprimirLog(INFO, "Algoritmo de planificacion:", pszValor);
	}
	
	else{
		imprimirLog(WARNING, "Parametro invalido ingresado en la configuracion:", ptr);
		return FIN_WARNING;
	}

	return FIN_OK;
}
